﻿/*
  Copyright (c) 2011, Mikheev Rostislav
  Copyright (c) 2011, FreshFarsh team

  Steel Engine source code is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
/**
  font.h

  @author Mikheev Rostislav <hacenator@gmail.com>
  @date 16.06.2010
  @brief GUI font class header file
*/

#ifndef STEEL_GUI_FONT_H_
#define STEEL_GUI_FONT_H_

#include <stdarg.h>
#include <vector>
#include <string>
#include <stdint.h>
#include "GL/glew.h"

// FreeType Headers
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>
#include <freetype/ftoutln.h>
#include <freetype/fttrigon.h>

#include "common.h"
#include "log.h"
#include "exception.h"
#include "math.h"
#include "structures.h"
#include "io_file.h"
#include "system.h"

namespace _STEEL_NAMESPACE {
/**
* @class GUIFont
* User interface GUI class
*/
class GUIFont {
 public:
  GUIFont(); ///< GUIFont constructor
  GUIFont(const char *fontfile, int size); ///< GUIFont constructor with specified font file
  virtual ~GUIFont();

  void DrawTexture();

  void Print(int x, int y, const wchar_t *string);
  void PrintInRect(int x, int y, const char *string, Rect rect);
  void PrintMultilineInRect(int x, int y, const char *string, Rect rect, const Rect *textRect = NULL);
  void Printf(int x, int y, const wchar_t *format, ...);

  float TextHeight();
  virtual float TextWidth(const wchar_t *format, ...);

  RGBAColor get_color() {
    return _color;
  };

  void set_color(RGBAColor color) {
    _color =  color;
  };
  void set_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
    _color.r =  r;
    _color.g =  g;
    _color.b =  b;
    _color.a =  a;
  };

  float scale() {
    return _scale;
  };

  void set_scale(float value) {
    _scale = value;
  };

 private:
  /**
    Glyph structure
  */
  struct Glyph {
    float x1, x2;   ///< glyph x texture coordinates
    float y;        ///< glyph y texture coordinate
    float width;    ///< glyph width
  };

  Glyph * _glyphs; ///< glyphs data
  int * _charmap; ///< characters map

  GLuint _texture; ///< Font texture identifier
  GLuint _index_buffer, _vertex_buffer; ///< VBO Buffers

  float _vertex_array[4][3]; ///<

  int _size; ///<font

  float _scale; ///< font scale value

  RGBAColor _color; ///< font color

  //char _charlen[256]; ///< characters

  int _line_height; ///< line height
  float _tex_line_height; ///< line height in texture coordinates

  /**
  * Print Single Character
  * @param x
  *     X coordinate
  * @param y
  *     Y coordinate
  * @param p
  *     Character to print
  */
  void PrintChar(int x, int y, const wchar_t *p);
///////////////////////////////////////////////////////////////

/*
public:
  vUIFont() { };
  vUIFont(const char * filename) { };
  virtual ~vUIFont() { };

  UIRGBA getColor() { return _color; };
  void setColor(UIRGBA color) { _color =  color; };
  void setColor(ubyte r, ubyte g, ubyte b, ubyte a) { _color.r =  r; _color.g =  g; _color.b =  b; _color.a =  a; };

  void setScale(float value) { _scale = value; };
  float getScale() { return _scale; };

  virtual void print(int x, int y, char * string) { }
  virtual void printInRect(int x, int y, char * string, UIRect rect) { }
  virtual void printMultilineInRect(int x, int y, char * string, UIRect rect, UIRect * textRect = NULL) { }
  virtual void printf(int x, int y, char * format, ...) { }

  virtual UIRect multilineTextRect(int maxWidth, char * format, ...) {
    float offsetX = 0;
    float offsetY = 0;
    UIRect textRect = {0, 0, 0, 0};

    // TODO: rect размером меньше одного символа

    if (format != NULL) {
      // собираем текст
      char text[1024];
      va_list ap;
      va_start(ap, format);
      vsprintf(text, format, ap);
      va_end(ap);

      char * p;
      p = text;

      // считаем посимвольно
      while (*p) {
        offsetX += (_scale * _charlen[(ubyte)*p]);

        // переход на другую строку
        if ((offsetX > maxWidth) || (*p == '\n'))  {
          offsetY += _scale * 32;
          offsetX = 0;
        }

        p++;
      }

      textRect.left = 0;
      textRect.top = 0;
      textRect.right = (offsetY != 0 ? maxWidth : offsetX);
      textRect.bottom = offsetY + _scale * 32;
    }

    return textRect;
  }

  virtual float textWidthTo(char * text, int pos) {
    char * str;
    float width = 0;

    if (text == NULL)
      return 0;

    if (pos > strlen(text))
      return 0;

      str = text + pos;

      do {
        width += _scale * _charlen[(unsigned char)*str];
      } while(*--str);

      return width;
    }
  };
*/
};

}

#endif /* STEEL_GUI_FONT_H_ */
